package com.magist.core.util;

import com.magist.core.annotation.Compare;
import com.magist.core.entity.BaseEntity;
import com.magist.core.exception.BusinessException;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;


/**
 * bean类工具
 *
 * @author dinglong 2017年8月7日下午1:38:12
 */
public class BeanCompareUtil {

	private static final String	WRAP_HTML	= "<br>";

	/**
	 * 分析两个对象不同值.对使用com.travel.base.annotation.Compare标志的字段进行判断是否为不同的值。不同则输出. 暂时不支持父类对象属性
	 *
	 * @param s 原来的
	 * @param t 修改后的
	 * @return
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static <T extends Object> String compare(T s, T t) {
		StringBuffer sb = new StringBuffer();
		List<Field> fdL = new ArrayList<Field>();
		Class clazz = s.getClass();
		while (!clazz.equals(BaseEntity.class) && !clazz.equals(Object.class)) {
			fdL.addAll(Arrays.asList(clazz.getDeclaredFields()));
			clazz = clazz.getSuperclass();
		}
		for (Field fi : fdL) {
			Compare cm = fi.getAnnotation(Compare.class);
			if (cm != null) {
				fi.setAccessible(true);
				// 原值
				String beforeValue = getValue(fi, s, cm);
				// 更新后的值
				String afterValue = getValue(fi, t, cm);
				if (!beforeValue.equals(afterValue)) {
					sb.append(cm.value()).append(":").append("[" + beforeValue + "]").append("改成[" + afterValue + "]").append(";");
				}
			}
		}
		return sb.toString();
	}

	/**
	 * 分析对象数据,返回内容.
	 *
	 * @param s
	 * @return
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static String info(Object s) {
		StringBuffer sb = new StringBuffer();
		List<Field> fdL = new ArrayList<Field>();
		Class clazz = s.getClass();
		while (!clazz.equals(BaseEntity.class) && !clazz.equals(Object.class)) {
			fdL.addAll(Arrays.asList(clazz.getDeclaredFields()));
			clazz = clazz.getSuperclass();
		}
		for (Field fi : fdL) {
			Compare cm = fi.getAnnotation(Compare.class);
			if (cm != null) {
				fi.setAccessible(true);
				String valueStr = getValue(fi,s,cm);
				if(!"空".equals(valueStr)) {
					sb.append(cm.value()).append(":").append("[" + valueStr + "]").append(";");
				}
			}
		}
		return sb.toString();
	}

	// 获取String值
	private static String getValue(Field fi, Object s, Compare cm) {
		String d1 = "空";
		try {
			Object fileValue = fi.get(s);
			if (fileValue != null) {
				// 判断类型
				// 时间转为yyyy-MM-dd
				if (fi.getGenericType().equals(Date.class)) {
					d1 = DateUtil.toString((Date) fileValue, DateUtil.yyyy_MM_dd);
				} else {
					d1 = fileValue.toString();
					// 枚举转换
					String enumClass = cm.enumClass();
					if (!StringUtils.isEmpty(enumClass)) {
						String transEnum = "";
						String[] enumItems = d1.split(",");
						for (String item : enumItems) {
							Object[] enumConstants = Class.forName(enumClass).getEnumConstants();
							for (Object enumConstant : enumConstants) {
								String code = ReflectionUtil.invokeMethod(enumConstant, "getCode", null).toString();
								if (code.equals(item)) {
									String desc = ReflectionUtil.invokeMethod(enumConstant, "getDesc", null).toString();
									transEnum += desc + ",";
									break;
								}
							}
						}
						if (transEnum.contains(",")) {
							d1 = transEnum.substring(0, transEnum.length() - 1);
						}
					}
				}
			}
		}catch (Exception e) {
			return d1;
		}
		return d1;
	}

	public static StringBuffer joinInfo(StringBuffer sb, String title, Object s, Boolean wrap) {
		if (ObjectUtils.isEmpty(sb))
			sb = new StringBuffer();
		try {
			String info = info(s);
			if (!StringUtils.isEmpty(info)) {
				sb = sb.append(title).append(info);
				if (wrap)
					sb = sb.append(WRAP_HTML);
			}
		} catch (Exception e) {
			throw new BusinessException("", e);
		}
		return sb;
	}

	public static <T extends Object> StringBuffer joinCompare(StringBuffer sb, String title, T s, T t, Boolean wrap) {
		if (ObjectUtils.isEmpty(sb))
			sb = new StringBuffer();
		try {
			String info = compare(s, t);
			if (!StringUtils.isEmpty(info)) {
				sb = sb.append(title).append(info);
				if (wrap)
					sb = sb.append(WRAP_HTML);
			}
		} catch (Exception e) {
			return sb;
		}
		return sb;
	}

}
